package com.mifa.loan.common.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * SignVaildUtils
 *
 * @author zhangsl
 * @date 2018/9/11 20:23
 * @dec 数据加签
 */
public class SignVaildUtils {

    /**
     * 数据加签
     */
    public static String sign(String appkey, String query, String body) {
        StringBuffer signPre = new StringBuffer();
        if (StringUtils.isNotBlank(query)) {
            signPre.append(analyzeData(query)).append("#");
        }
        if (StringUtils.isNotBlank(body)) {
            signPre.append(analyzeData(body)).append("#");
        }
        if (StringUtils.isNotBlank(appkey)) {
            signPre.append("appkey=").append(appkey);
        }
        String sign = null;
        try {
            sign = DigestUtils.md5Hex(signPre.toString().getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("签名过程中出现错误,默认编码集:UTF-8");
        }
        return sign;
    }

    /**
     * 数据解析
     */
    public static String analyzeData(String source) {
        String result = null;
        if (JSON_TYPE.JSON_TYPE_OBJECT.equals(getJSONType(source))) {
            //jsonObject
            result = analyzeObject(JSONObject.parseObject(source));
        }
        if (JSON_TYPE.JSON_TYPE_ARRAY.equals(getJSONType(source))) {
            //jsonArray
            result = analyzeArray(JSONArray.parseArray(source));
        }
        if (JSON_TYPE.JSON_TYPE_ERROR.equals(getJSONType(source))) {
            //Other
            result = source;
        }
        return result;
    }

    private static String analyzeObject(JSONObject jsonObject) {
        StringBuffer result = new StringBuffer("{");
        List<String> keyList = jsonObject
                .keySet()
                .stream()
                .sorted()
                .collect(Collectors.toList());

        for (int i = 0; i < keyList.size(); i++) {
            String key = keyList.get(i);
            String value = jsonObject.getString(key);
            JSON_TYPE jsonType = getJSONType(value);
            if (JSON_TYPE.JSON_TYPE_ARRAY.equals(jsonType)) {
                //JSONArray
                result.append(key + "=" + analyzeArray(JSONArray.parseArray(value)));
            } else if (JSON_TYPE.JSON_TYPE_OBJECT.equals(jsonType)) {
                //JSONObject
                result.append(key + "=" + analyzeObject(JSONObject.parseObject(value)));
            } else if (JSON_TYPE.JSON_TYPE_ERROR.equals(jsonType)) {
                //基本类型判断
                result.append(key + "=" + value);
            }
            //添加分隔符
            if (i != (keyList.size() -1)) {
                result.append(",");
            }
        }
        return result.append("}").toString();
    }

    private static String analyzeArray(JSONArray jsonArray) {
        StringBuffer result = new StringBuffer("[");
        for (int i = 0; i < jsonArray.size(); i++) {
            String value = jsonArray.getString(i);
            JSON_TYPE jsonType = getJSONType(value);
            if (JSON_TYPE.JSON_TYPE_ARRAY.equals(jsonType)) {
                //JSONArray
                result.append(i + "=" + analyzeArray(JSONArray.parseArray(value)));
            } else if (JSON_TYPE.JSON_TYPE_OBJECT.equals(jsonType)) {
                //JSONObject
                result.append(i + "=" + analyzeObject(JSONObject.parseObject(value)));
            } else if (JSON_TYPE.JSON_TYPE_ERROR.equals(jsonType)) {
                //基本类型判断
                result.append(i + "=" + value);
            }
            //添加分隔符
            if (i != (jsonArray.size() -1)) {
                result.append(",");
            }
        }
        return result.append("]").toString();
    }

    public enum JSON_TYPE{
        /**JSONObject*/
        JSON_TYPE_OBJECT,
        /**JSONArray*/
        JSON_TYPE_ARRAY,
        /**不是JSON格式的字符串*/
        JSON_TYPE_ERROR
    }

    public static JSON_TYPE getJSONType(String str){
        if(StringUtils.isEmpty(str)){
            return JSON_TYPE.JSON_TYPE_ERROR;
        }

        final char[] strChar = str.substring(0, 1).toCharArray();
        final char firstChar = strChar[0];

        if(firstChar == '{'){
            return JSON_TYPE.JSON_TYPE_OBJECT;
        }else if(firstChar == '['){
            return JSON_TYPE.JSON_TYPE_ARRAY;
        }else{
            return JSON_TYPE.JSON_TYPE_ERROR;
        }
    }
}
